package com.tmsps.common.filter;

import com.tmsps.common.annotation.JFilter;
import com.tmsps.common.annotation.JFilters;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJacksonValue;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.AbstractMappingJacksonResponseBodyAdvice;

/**
 * @author geek
 */
@ControllerAdvice
public class JFilterResponseBodyAdvice extends AbstractMappingJacksonResponseBodyAdvice {

    @Override
    public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
        return super.supports(returnType, converterType) && ( returnType.hasMethodAnnotation(JFilters.class) || returnType.hasMethodAnnotation(JFilter.class) );
    }


    @Override
    protected MappingJacksonValue getOrCreateContainer(Object body) {
        return (body instanceof MappingJacksonValue ? (MappingJacksonValue) body : new JFilterValue(body));
    }

    @Override
    protected void beforeBodyWriteInternal(MappingJacksonValue bodyContainer, MediaType contentType,
                                           MethodParameter returnType, ServerHttpRequest request,
                                           ServerHttpResponse response) {

        if (returnType.hasMethodAnnotation(JFilters.class)) {
            ((JFilterValue) bodyContainer).setJfilters(returnType.getMethodAnnotation(JFilters.class).value());
        } else if (returnType.hasMethodAnnotation(JFilter.class)) {
            ((JFilterValue) bodyContainer).setJfilters(
                    new JFilter[]{returnType.getMethodAnnotation(JFilter.class)}
            );
        }

    }

}
